public class NotEqualToOp extends ComparisonOp {
	public NotEqualToOp() {
		super("!=");
	}
	
	@Override
	public boolean isNotEqualToOp () {
		return true;
	}
	
	@Override
	public STO checkOperands(STO left, STO right) {
		if (left.isError()) { 
			return left;
		}
		if (right.isError()){
			return right;
		}
		STO sto;
		Type l_type = left.getType();
		Type r_type = right.getType();
		boolean l_numeric = l_type.isNumeric();
		boolean r_numeric = r_type.isNumeric();
		// both operand types must be numeric, otherwise throw error
		if ( (l_numeric && r_numeric) || (l_type.isBool() && r_type.isBool()) ){
			if(left.isConst() && right.isConst()) {
				sto = new ConstSTO(left.getName() + "!=" + right.getName(), new BoolType());
			}
			else {
				if (!left.isConst()) {
					sto = new ExprSTO(left.getName(), new BoolType());
				} else {
					sto = new ExprSTO(right.getName(), new BoolType());
				}
			}
		}
		else if(l_type.isPointerType() || r_type.isPointerType()) {
			if(!(l_type.isPointerType() && r_type.isPointerType())) {
				if((l_type.isFuncPtrType() && r_type.isNullPtrType()) || (l_type.isNullPtrType() && r_type.isFuncPtrType())) {
					sto = new ExprSTO(l_type.getName() + "!=" + r_type.getName(), new BoolType());
				}
				else {
					sto = new ErrorSTO("error17_Expr");
				}
			}
			else {	// both left and right are PointerType
				// Check 17: Add Checks to allow equality check for nullptrs
				if(l_type.isNullPtrType() || r_type.isNullPtrType()) {
					if(l_type.isNullPtrType() && r_type.isNullPtrType()) {
						sto = new ConstSTO(l_type.getName() + "!=" + r_type.getName(), new BoolType(), 1);
					} else {
						sto = new ExprSTO(l_type.getName() + "!=" + r_type.getName(), new BoolType());
					}
				}
				else {
					if(!((PointerType)l_type).getBaseType().isEquivalentTo(((PointerType)r_type).getBaseType())) {
						sto = new ErrorSTO("error17_Expr");
					} else {
						sto = new ExprSTO(l_type.getName() + "!=" + r_type.getName(), new BoolType());
					}
				}
			}
		}
		else {
			sto = new ErrorSTO("error1b_Expr");
		}
		return sto;
	}
	
	@Override
	public STO calculate(ConstSTO left, ConstSTO right) {
		ConstSTO sto;
		int result;
		if (left.getFloatValue() != right.getFloatValue()) {
			result = 1;
		} else {
			result = 0;
		}
		sto = new ConstSTO((left.getName() + "!=" + right.getName()), new BoolType(), 
				  Integer.toString(result));
		return sto;
	}
}
